#!/bin/bash
# File Name   : cg_server.sh
# Author      : moshan
# Mail        : mo_shan@yeah.net
# Version     : 1.0
# Created Time: 2025-03-12 11:08:00
# Function    : cgroup规则管理
#########################################################################
set -e -o pipefail

work_dir="/opt/soft/cgroup"
conf_dir="${work_dir}/conf"

localhost_ip="$(/sbin/ip a 2>/dev/null|grep inet|grep brd|grep scope|awk '{print $2}'|awk -F'/' '{print $1}'|head -1)" || true

. /etc/profile || true

export PATH="/opt/soft/mysql80/bin:/opt/soft/mysql57/bin:${PATH}"

declare -A dev_host_mount

dev_host_mount=(
    ["10.46.128.5"]="/opt" 
    ["10.46.128.8"]="/opt"
    ["192.168.168.11"]="/data0"
    ["192.168.168.12"]="/data0"
    ["192.168.168.13"]="/data0"
    ["192.168.168.14"]="/data0"
    ["192.168.168.15"]="/data0"
    ["192.168.168.21"]="/data0"
    ["192.168.168.22"]="/data0"
    ["192.168.168.23"]="/data0"
    ["192.168.168.33"]="/opt"
    ["192.168.168.40"]="/work"
    ["192.168.168.41"]="/work"
    ["192.168.168.42"]="/work"
)

declare -A cg_init_value
cg_init_value=(

    ["cpu"]=8
    ["memory"]=16
    ["io_read"]=160
    ["io_write"]=160
    ["iops_read"]=8000
    ["iops_write"]=8000
)

function f_usage()
{
    echo
    echo -e "$(printf %-16s "Usage: \033[35m$0")\033[0m\n"
    echo -e "$(printf %-16s ) \033[32m[ -p 3306 ]                              \033[33m端口"
    echo -e "$(printf %-16s ) \033[32m[ -r master|slave|real ]                 \033[33m角色类型"
    echo -e "$(printf %-16s ) \033[32m[ -o add|del|update ]                    \033[33m操作类型"
    echo -e "$(printf %-16s ) \033[32m[ -t mysql|tidb ]                        \033[33m数据库类型，暂时只支持mysql tidb"
    echo -e "$(printf %-16s ) \033[32m[ -T dev|oltp ]                          \033[33m数据库类型，暂时只支持mysql tidb"
    echo -e "$(printf %-16s ) \033[32m[ -k cpu|memory|mem|io_read|iops_read ]  \033[33m资源组"
    echo -e "$(printf %-16s ) \033[32m[ -v 4 ]                                 \033[33mcpu表示核心，内存表示GB，iops表示次数，io表示MB"
    echo -e "$(printf %-16s ) \033[32m[ -i igid ]                              \033[33migid"
    echo -e "$(printf %-16s ) \033[32m[ -m mountpoint ]                        \033[33m数据盘挂载点"
    echo -e "$(printf %-16s ) \033[32m[ -h ]                                   \033[33m帮助信息"
    echo
    exit 1
}

function f_check_master()
{
    declare exe_state is_master
    exe_state="0"
    is_master="$(timeout 5s ${mysql_comm} -NBe "show slave status\G" 2>/dev/null|wc -l)" || exe_state="${?}"

    if [ "${exe_state}x" != "0x" ] 
    then
        exe_state="0"
        is_master="$(timeout 5s ${local_mysql_comm} -NBe "show slave status\G" 2>/dev/null|wc -l)" || exe_state="${?}"
        mysql_comm="${local_mysql_comm}"
    fi

    if [ "${is_master}x" != "0x" ] || [ "${exe_state}x" != "0x" ]
    then
        return 1
    fi
}

function f_prepare()
{
    [ "${#}x" == "0x" ] && return 0

    while getopts :p:r:o:t:T:k:v:m:i:h OPTION
    do
        case "$OPTION" in
            p)
                PORT=$OPTARG
                ;;
            r)
                ROLE=$OPTARG
                ;;
            o)
                OPTS=$OPTARG
                ;;
            t)
                DBTYPE=$OPTARG
                ;;
            T)
                ENV=$OPTARG
                ;;
            k)
                ISOKEY=$OPTARG
                ;;
            v)
                ISOVALUE=$OPTARG
                ;;
            m)
                MOUNT=$OPTARG
                ;;
            i)
                IGID=$OPTARG
                ;;
            h)f_usage;;
            :)echo -e "\n'-${OPTARG}' : 这个选项需要一个值";f_usage;;
            ?|*)echo -e "\n'-${OPTARG}' : 不识别这个选项.";f_usage;;
        esac
    done

    if [ -z "${PORT}" ] || [ -z "${ROLE}" ] || [ -z "${OPTS}" ] || [ -z "${DBTYPE}" ] || [ -z "${ISOKEY}" ] || [ -z "${IGID}" ]
    then
        f_usage
        return 1
    fi

    if [ "${ENV}x" != "devx" ] && [ "${ENV}x" != "oltpx" ]
    then
        return 1
    else
        source ${conf_dir}/${ENV}.conf
    fi

    [ "${ROLE}x" == "allx" ] && ROLE="master','slave','real"

    declare sql PIDPATH ISTATE

    if [ "${DBTYPE}x" == "mysqlx" ]
    then
        tab="tb_mysql_instance"
        [ "${ENV}x" == "devx" ] && tab="tb_test_mysql_instance"
        sql="select rshost from ${tab} where istate = '0' and rsrole in ('${ROLE}') and rsport = ${PORT} and igid = ${IGID}"
    elif [ "${DBTYPE}x" == "tidbx" ]
    then
        tab="tb_tidb_instance"
        [ "${ENV}x" == "devx" ] && tab="tb_test_tidb_instance"
        sql="select rshost from tb_tidb_instance where istate = 1 and rsrole in ('${ROLE}') and rsport = ${PORT} and igid = ${IGID}"
    else
        return 1
    fi

    PIDPATH="/work/${DBTYPE}${PORT}/var/mysql.pid"

    ISTATE="3"

    mysql_comm="${mysql_path} -u${mysql_user} -p${mysql_pass} -h${mysql_host} -P ${mysql_port} ${mysql_db}"

    local_mysql_comm="${mysql_path} -u${mysql_user} -p${mysql_pass} -h${localhost_ip} -P ${mysql_port} ${mysql_db}"

    f_check_master

    declare -a IPLIST
    IPLIST=($(${mysql_comm} -NBe "${sql}" 2>/dev/null))

    declare HOST
    echo ${sql}
    sql=""

    if [ "${ISOKEY}x" == "allx" ]
    then
        ISOKEY="cpu,memory,io_read,io_write,iops_read,iops_write"
    fi

    for ikey in $(echo "${ISOKEY}"|tr "," " ")
    do
        [ -z "${ISOVALUE}" ] && ivalue="${cg_init_value["${ikey}"]}"

        for HOST in ${IPLIST[@]}
        do
            [ -z "${MOUNT}" ] && imount="${dev_host_mount["${HOST}"]}" || imount="${MOUNT}"
            sql="${sql}insert into tb_cgroup_manager (id,order_id,igid,rshost,rsport,rule,dbtype,isotype,isovalue,istate,pidpath,mountpoin,a_time,u_time,e_time,alert_type,alert_channel,remarks)
                     value(0,0,${IGID},'${HOST}',${PORT},'${OPTS}','${DBTYPE}','${ikey}','${ivalue}',${ISTATE},'${PIDPATH}','${imount}',now(),now(),'9999-12-31 23:59:59','user','moshan','');"
        done
    done
    echo "begin;${sql}commit;" |${mysql_comm} -NB 2>/dev/null

    return 0
}

function f_main()
{
    [ -f "/opt/soft/cgroup/stop_file_long" ] && return 0

    f_prepare "${@}"

}

f_main "${@}"
